import os
import subprocess
import gtk
import gedit
import string
import gtksourceview2

from gettext import gettext as _

ui_str1 = """
<ui>
    <popup name="NotebookPopup">
        <placeholder name="NotebookPupupOps_1"/>   
        <separator/>
        <menuitem action="SvnUpdateFile"/>
        <menuitem action="SvnCommitFile"/>
        <menuitem action="SvnDiffFile"/>
        <menuitem action="SvnRevertFile"/>
    </popup>
</ui>
"""

ui_str2 = """
<ui>
    <popup name="FilePopup">
        <menuitem action="SvnUpdateFile"/>
        <menuitem action="SvnCommitFile"/>
        <menuitem action="SvnDiffFile"/>
    </popup>
</ui>
"""


ui_str3 = """
<ui>
  <menubar name="MenuBar">
    <menu name="SvnMenu" action="SvnMenu">
      <placeholder name="ToolsOps_4">
        <menuitem name="Svn checkout" action="SvnCheckout"/>
        <separator/>
        <menuitem name="Svn Update File" action="SvnUpdateFile"/>
        <menuitem name="Svn Commit File" action="SvnCommitFile"/>
        <menuitem name="Svn Diff File" action="SvnDiffFile"/>
        <menuitem action="SvnRevertFile"/>
        <separator/>
        <menuitem name="Svn Update Dir" action="SvnUpdateDir"/>
        <menuitem name="Svn Commit Dir" action="SvnCommitDir"/>
        <menuitem name="Svn Diff Dir" action="SvnDiffDir"/>
        <menuitem action="SvnRevertDir"/>
        <separator/>
      </placeholder>
    </menu>
  </menubar>
</ui>
"""

class ExamplePyWindowHelper:
    def __init__(self, plugin, window):
        self._window = window
        self._plugin = plugin

        # Insert menu items
        self._insert_menu()

    def deactivate(self):
        # Remove any installed menu items
        self._remove_menu()

        self._window = None
        self._plugin = None
        self._action_group = None

    def _insert_menu(self):
        # create a new action group
        action_group = gtk.ActionGroup("SvnActions")
        action_group.add_actions([("SvnMenu", None, ("Svn"), None,
                                        _("Open the svn menu"), None)])
        action_group.add_actions([("SvnUpdateFile", None, _("Svn Update"),
                                         None, _("Do an svn update on file"),
                                         self.svn_update_file)])
        action_group.add_actions([("SvnUpdateDir", None, _("Svn Update (dir)"),
                                         None, _("Do an svn update on dir"),
                                         self.svn_update_dir)])
        action_group.add_actions([("SvnCommitFile", None, _("Svn Commit"),
                                         None, _("Do an svn commit on file"),
                                         self.svn_commit_file)])
        action_group.add_actions([("SvnCommitDir", None, _("Svn Commit (dir)"),
                                         None, _("Do an svn commit on dir"),
                                         self.svn_commit_dir)])
        action_group.add_actions([("SvnDiffFile", None, _("Svn Diff"),
                                         None, _("Do an svn diff on file"),
                                         self.svn_diff_file)])
        action_group.add_actions([("SvnDiffDir", None, _("Svn Diff (dir)"),
                                         None, _("Do an svn diff on dir"),
                                         self.svn_diff_dir)])
        action_group.add_actions([("SvnRevertFile", None, _("Svn Revert"),
                                         None, _("Do an svn revert on file"),
                                         self.svn_revert_file)])        
        action_group.add_actions([("SvnRevertDir", None, _("Svn Revert (dir)"),
                                         None, _("Do an svn revert on dir"),
                                         self.svn_revert_dir)])
        action_group.add_actions([("SvnCheckout", None, _("Svn Checkout"),
                                         None, _("Do an svn checkout"),
                                         self.svn_checkout)])

        # save it
        self._action_group = action_group
        
        # insert it
        mgr = self._window.get_ui_manager()
        mgr.insert_action_group(action_group, -1)
        self._ui_id = mgr.add_ui_from_string(ui_str1)
        self._ui_id = mgr.add_ui_from_string(ui_str2)
        self._ui_id = mgr.add_ui_from_string(ui_str3)
        
    def _remove_menu(self):
        # Get the GtkUIManager
        manager = self._window.get_ui_manager()

        # Remove the ui
        manager.remove_ui(self._ui_id)

        # Remove the action group
        manager.remove_action_group(self._action_group)

        # Make sure the manager updates
        manager.ensure_update()

    def svn_checkout(self, action):
        svn_dir = self.show_dialog("Svn repository", "URL")
        local_dir = self.show_dialog("Local directory", "Path")
        
        if svn_dir != None and local_dir != None:
            subprocess.Popen(["/usr/bin/svn", "checkout", svn_dir, local_dir])
            self.show_popup("Checkout done in " + local_dir)
        else:
            self.show_popup("Checkout canceled")

    def update_ui(self):
        self._action_group.set_sensitive(self._window.get_active_document() != None)

    def svn_update_file(self, action):
        doc = self._window.get_active_document().get_uri_for_display()
        self.svn_update(doc)

    def svn_update_dir(self, action):
        doc = self._window.get_active_document()
        uri = doc.get_uri_for_display()
        filename = doc.get_short_name_for_display()
        filedir = string.replace(uri, filename, "")
        self.svn_update(filedir)        
        return

    def svn_update(self, obj):
        subprocess.Popen(["/usr/bin/svn", "update", obj])
        self.show_popup("Update done")

    def svn_commit_file(self, action):
        doc = self._window.get_active_document().get_uri_for_display()
        self.svn_commit(doc)
        
    def svn_commit_dir(self, action):
        doc = self._window.get_active_document()
        uri = doc.get_uri_for_display()
        filename = doc.get_short_name_for_display()
        filedir = string.replace(uri, filename, "")
        self.svn_commit(filedir)

    def svn_commit(self, obj):
        mess = self.show_dialog("Commit", "Message")
        if mess != None:
            subprocess.Popen(["/usr/bin/svn", "commit", "-m", "\"", mess, "\"", obj])
            self.show_popup("Commit done")
        else:
            self.show_popup("Commit canceled")

    def svn_diff_file(self, action):
        doc = self._window.get_active_document().get_uri_for_display()
        self.svn_diff(doc)

    def svn_diff_dir(self, action):
        doc = self._window.get_active_document()
        uri = doc.get_uri_for_display()
        filename = doc.get_short_name_for_display()
        filedir = string.replace(uri, filename, "")
        self.svn_diff(filedir)


    def svn_diff(self, obj):
        print "DIFFING " + obj
        s = subprocess.Popen(["/usr/bin/svn", "diff", obj], stdout = subprocess.PIPE)
        diffdoc = self._window.create_tab(True).get_document()
        diffdoc.set_language(gtksourceview2.language_manager_get_default().get_language('diff'))
        diffdoc.set_text(s.communicate()[0])
        return

    def svn_revert_file(self, action):
        doc = self._window.get_active_document().get_uri_for_display()
        self.svn_revert(doc)
        return
    
    def svn_revert_dir(self, action):
        doc = self._window.get_active_document()
        uri = doc.get_uri_for_display()
        filename = doc.get_short_name_for_display()
        filedir = string.replace(uri, filename, "")
        self.svn_revert(filedir)
        return
    
    def svn_revert(self, obj):
        s = subprocess.Popen(["/usr/bin/svn", "revert", obj])
        self.show_popup("Reverted " + obj)
        return
        
    def show_popup(self, msg):
        dialog = gtk.MessageDialog(None,
                gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                gtk.MESSAGE_INFO, gtk.BUTTONS_OK, msg)
        dialog.run()
        dialog.destroy()
        return

    def show_dialog(self, title, message):
    
        dialog = gtk.Dialog(title, None, 0,
            (gtk.STOCK_OK, gtk.RESPONSE_OK,
            gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))

        hbox = gtk.HBox(False, 8)
        hbox.set_border_width(8)
        dialog.vbox.pack_start(hbox, False, False, 0)

        stock = gtk.image_new_from_stock(
                gtk.STOCK_DIALOG_QUESTION,
                gtk.ICON_SIZE_DIALOG)
        hbox.pack_start(stock, False, False, 0)

        table = gtk.Table(2, 2)
        table.set_row_spacings(4)
        table.set_col_spacings(4)
        hbox.pack_start(table, True, True, 0)

        label = gtk.Label(message)
        label.set_use_underline(True)
        table.attach(label, 0, 1, 0, 1)
        local_entry1 = gtk.Entry()
        table.attach(local_entry1, 1, 2, 0, 1)
        label.set_mnemonic_widget(local_entry1)

        dialog.show_all()

        if dialog.run() == gtk.RESPONSE_OK:
            ret = local_entry1.get_text()
        else:
            ret = None
            
        dialog.destroy()
        return ret
        
    # Menu activate handlers
    def on_clear_document_activate(self, action):
        doc = self._window.get_active_document()
        if not doc:
            return

        doc.set_text('')


class ExamplePyPlugin(gedit.Plugin):
    def __init__(self):
        gedit.Plugin.__init__(self)
        self._instances = {}

    def activate(self, window):
        self._instances[window] = ExamplePyWindowHelper(self, window)

    def deactivate(self, window):
        self._instances[window].deactivate()
        del self._instances[window]

    def update_ui(self, window):
        self._instances[window].update_ui()
                  
